#include "obdii_4g.h"
#include <QThread>
#include <QByteArray>
#include <QMutex>

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <memory.h>

#include <time.h>
#include "agreement/agreement.h"
#include "agreement/obd_shanghai.h"
#include "DateTime.h"
#include "agreement/upload.h"

static QMutex mutex;
static QMutex obd_mutex;
enum ssl_type OBDII_4G::ssl;
//static QTcpSocket *obd_socket=NULL;
static OBDII_4G *thread_pond[1024] = {NULL} ;  // 连接池
static int socket_pond_init = 0;    // 初始化标志
static const struct agreement_ofp* _agree_obd=NULL;

static uint8_t obd_buf[1024*10];
static uint8_t msg_buf[4096];
static struct report_gps gps;
static OBD_DATA obd;
static double simulation_lon=10.0f;
static double simulation_lat=10.0f;

typedef void (*send_func)(const int sockfd, const void *buf, const uint16_t len);

static void obd_upload_start(void);
static enum upload_status obd_upload(const int sockfd, send_func send);
static void obd_init(const enum ssl_type _ssl);
static void obd_login(const int sockfd, send_func send);
static void obd_logout(const int sockfd, send_func send);
static void obd_UTC(const int sockfd, send_func send);
static int obd_report(const int sockfd, send_func send);
static int obd_report_later(const int sockfd, send_func send);
static enum upload_status obd_upload(const int sockfd, send_func send);
static void csend(const int sockfd, const void *buf, const uint16_t len);
static qint64 crecv(const int sockfd, void *buf, const uint16_t _rsize);
static qint64 cmrecv(const int sockfd, void *buf, const uint16_t _rsize, int msecs = 30000);

OBDII_4G::OBDII_4G(QString _objName, QObject *parent) : SocketThread(_objName, parent)
{
    thread_id = 0;
}

int OBDII_4G::get_thread_id()
{
    int id;
    int _size = sizeof(thread_pond)/sizeof(thread_pond[0]);
    mutex.lock();
    if(1!=socket_pond_init)
    {
        memset(thread_pond, 0, sizeof(thread_pond));
        socket_pond_init = 1;
    }
    for(id=0; id<_size; id++)
    {
        if(NULL == thread_pond[id])
        {
            thread_pond[id] = this;
            break;
        }
    }
    mutex.unlock();
    if(_size==id) return -1;
    return id;
}

int OBDII_4G::init(const QString _hostName, const quint16 _port)
{
    //SocketThread::init(_hostName, _port);
    obd_init(ssl);
    thread_id = get_thread_id();
    if(thread_id<0) return -1;

#if 1
    // 1. 创建TCP套接字对象
    socket = new QTcpSocket(this);
    socket->abort();        //取消原有连接
    // 2. 已连接、数据可读、失败信号连接
    //connect(socket, &QTcpSocket::connected, this, &SocketClient::connected);
    connect(socket, &QIODevice::readyRead, this, &OBDII_4G::readyRead);
    typedef void (QAbstractSocket::*QAbstractSocketErrorSignal)(QAbstractSocket::SocketError);
    connect(socket, static_cast<QAbstractSocketErrorSignal>(&QTcpSocket::error), this, &OBDII_4G::error);
    //3. 与服务器端建立连接
    //socket->connectToHost("39.108.72.130", 9910, QTcpSocket::ReadWrite);
    socket->connectToHost(_hostName, _port, QTcpSocket::ReadWrite);
    socket->waitForConnected();
    //4. 同步处理-等待数据可读
    //socket->waitForReadyRead();
#if 0
    socket->write("Hello", 5);
#endif

#else
#endif
    //obd_socket = this->socket;
    //socket_pond[thread_id] = this->socket;
    return 0;
}
void obd_init(const enum ssl_type _ssl)
{
    memset(&gps, 0, sizeof (gps));
    gps.status = 0x3<<1;
    gps.speed = 30;
    simulation_lon = 30/0.000001f;
    simulation_lat = 40/0.000001f;
    memset(&obd, 0, sizeof (obd));
    memcpy(obd.ECUInfo.VIN, "VIN1234567890ABCDEFGHIJ", 19);
    obd.RTData.Velocity = 100;
    obd.RTData.EngineRev = 200;
    obd.RTData.Mileage = 300;
    obd.RTData.FuelConsumption = 400;
    _agree_obd = create_agree_obd_shanghai();
    //_agree_obd->init(0, (const uint8_t*)"IMEI1234567890ABCDEF", 2, "INFO");
    //_agree_obd->init(0, (const uint8_t*)"IMEI1234567890ABCDEF", 2, "RSA");
    switch(_ssl)
    {
        case SSL_RSA:
            _agree_obd->init(0, (const uint8_t*)"IMEI1234567890ABCDEF", 2, "RSA");
            break;
        case SSL_SM2:
            _agree_obd->init(0, (const uint8_t*)"IMEI1234567890ABCDEF", 2, "INFO");
            break;
        case SSL_INFO:
        default:
            _agree_obd->init(0, (const uint8_t*)"IMEI1234567890ABCDEF", 2, "INFO");
            break;
    }
}
void obd_login(const int sockfd, send_func send)
{
    int len = 0;
    time_t timer = time(NULL);
    len = _agree_obd->login(timer, 0, (const uint8_t*)"VIN1234567890ABCDEF1234567890",  (const uint8_t*)"VIN1234567890ABCDEF", "ATT", obd_buf, sizeof (obd_buf));
    //printf("login pack len : %d\n", len);
    fflush(stdout);
//    decode_test(_agree_obd, obd_buf, (const uint16_t)len, msg_buf, sizeof (msg_buf));
//    fflush(stdout);
    //printf("write:%d\n", socket->write((char*)obd_buf, len)); fflush(stdout);
//    obd_socket->write((char*)obd_buf, len);
//    obd_socket->waitForBytesWritten();
    send(sockfd, (char*)obd_buf, len);
//    uint8_t buffer[sizeof(struct upload)];
//    // upload_init(const enum upload_cmd _cmd, const uint16_t pack_total, const uint16_t pack_index, const uint32_t checksum, const uint8_t Model[16], const uint8_t data[512], const uint16_t data_len);
//    struct upload* _load = upload_init(UPLOAD_LOGIN, 0, 0, 0x12345678, (const char*)"OBD1234567890ABCDEF", "Hello", 5);
//    memset(buffer, 0, sizeof (buffer));
//    len = upload_encode(_load, buffer, sizeof (buffer));
//    len = _agree_obd->encode(buffer, len, obd_buf, sizeof (obd_buf));
//    //printf("login pack encode len : %d\n", len);
//    socket->write((char*)obd_buf, len);
//    socket->waitForBytesWritten();
}

void obd_logout(const int sockfd, send_func send)
{
    int len = 0;
    time_t timer = time(NULL);
    len = _agree_obd->logout(timer, 0, obd_buf, sizeof (obd_buf));
    //printf("login pack len : %d\n", len);
    fflush(stdout);
//    decode_test(_agree_obd, obd_buf, (const uint16_t)len, msg_buf, sizeof (msg_buf));
//    fflush(stdout);
    //printf("write:%d\n", socket->write((char*)obd_buf, len)); fflush(stdout);
//    socket->write((char*)obd_buf, len);
//    socket->waitForBytesWritten();
    send(sockfd, (char*)obd_buf, len);
}

void obd_UTC(const int sockfd, send_func send)
{
    int len = 0;
    //time_t timer = time(NULL);
    len = _agree_obd->utc(obd_buf, sizeof (obd_buf));
    //printf("login pack len : %d\n", len);
    fflush(stdout);
//    decode_test(_agree_obd, obd_buf, (const uint16_t)len, msg_buf, sizeof (msg_buf));
//    fflush(stdout);
    //printf("write:%d\n", socket->write((char*)obd_buf, len)); fflush(stdout);
//    socket->write((char*)obd_buf, len);
//    socket->waitForBytesWritten();
    send(sockfd, (char*)obd_buf, len);
}

void update_simulation_data(struct report_gps* const _gps)
{
    _gps->speed = (_gps->speed+1)%125;
    simulation_lon = simulation_lon+1.3f;
    while(simulation_lon>180.0f) simulation_lon -= 180.0f;
    simulation_lat = simulation_lat+1.3f;
    while(simulation_lat>180.0f) simulation_lat -= 180.0f;
    _gps->longitude = (uint32_t)(simulation_lon/0.000001f);
    _gps->latitude = (uint32_t)(simulation_lat/0.000001f);
}

int obd_report(const int sockfd, send_func send)
{
    int push=0;
    int len = 0;
    int ret = 0;
    qint64 _size=0;
    time_t timer = time(NULL);
    update_simulation_data(&gps);
    obd.RTData.Velocity = (obd.RTData.Velocity+5)%700;
    obd.RTData.EngineRev = (obd.RTData.EngineRev+13)%1700;
    obd.RTData.Mileage = (obd.RTData.Mileage+3)%800;
    obd.RTData.FuelConsumption = (obd.RTData.FuelConsumption+7)%900;
    obd.DTCInfo.Current = 3;
    obd.DTCInfo.CurrentDTC[0] = '0';
    obd.DTCInfo.CurrentDTC[1] = '1';
    obd.DTCInfo.CurrentDTC[2] = '2';
    obd.DTCInfo.CurrentDTC[3] = '3';
    obd.DTCInfo.CurrentDTC[4] = '4';
    obd.DTCInfo.CurrentDTC[5] = '5';
    time(&timer);
    len = _agree_obd->report(shanghai_report_msg(timer, &obd, &gps, msg_buf, sizeof (msg_buf)), obd_buf, sizeof (obd_buf));
    //printf("report pack len : %d\n", len);
    fflush(stdout);
//    decode_test(_agree_obd, obd_buf, (const uint16_t)len, msg_buf, sizeof (msg_buf));
//    fflush(stdout);
    //printf("write:%d\n", socket->write((char*)obd_buf, len)); fflush(stdout);
//    socket->write((char*)obd_buf, len);
//    socket->waitForBytesWritten();
    send(sockfd, (char*)obd_buf, len);
    QThread::msleep(1000);
    _size = cmrecv(sockfd, obd_buf, sizeof (obd_buf), 1000);
    ret = decode_client(_agree_obd, (const uint8_t*)obd_buf, _size, msg_buf, sizeof (msg_buf), sockfd, csend);
    if(STATUS_CLIENT_PUSH==ret) // 推送固件
    {
        printf("STATUS_CLIENT_PUSH\n"); fflush(stdout);
        push=1;
    }
    return push;
}

int obd_report_later(const int sockfd, send_func send)
{
    int push=0;
    int len = 0;
    int ret = 0;
    qint64 _size=0;
    time_t timer = time(NULL);
    update_simulation_data(&gps);
    obd.RTData.Velocity = (obd.RTData.Velocity+5)%700;
    obd.RTData.EngineRev = (obd.RTData.EngineRev+13)%1700;
    obd.RTData.Mileage = (obd.RTData.Mileage+3)%800;
    obd.RTData.FuelConsumption = (obd.RTData.FuelConsumption+7)%900;
    time(&timer);
    len = _agree_obd->report_later(shanghai_report_msg(timer, &obd, &gps, msg_buf, sizeof (msg_buf)), obd_buf, sizeof (obd_buf));
    //printf("report pack len : %d\n", len);
    fflush(stdout);
//    decode_test(_agree_obd, obd_buf, (const uint16_t)len, msg_buf, sizeof (msg_buf));
//    fflush(stdout);
    //printf("write:%d\n", socket->write((char*)obd_buf, len)); fflush(stdout);
//    socket->write((const char*)obd_buf, len);
//    socket->flush();
//    socket->waitForBytesWritten();
    send(sockfd, (char*)obd_buf, len);
    QThread::msleep(1000);
    _size = cmrecv(sockfd, obd_buf, sizeof (obd_buf), 1000);
    ret = decode_client(_agree_obd, (const uint8_t*)obd_buf, _size, msg_buf, sizeof (msg_buf), sockfd, csend);
    if(STATUS_CLIENT_PUSH==ret) // 推送固件
    {
        printf("STATUS_CLIENT_PUSH\n"); fflush(stdout);
        push=1;
    }
    return push;
}
//static uint8_t msg_buf[4096];
static void csend(const int sockfd, const void *buf, const uint16_t len)
{
    //(void)sockfd;
    OBDII_4G *obd = NULL;
    mutex.lock();
    obd = thread_pond[sockfd];
    obd->send(sockfd, buf, (qint64)len);
    mutex.unlock();
}
static qint64 crecv(const int sockfd, void *buf, const uint16_t _rsize)
{
    qint64 _size=0;
    OBDII_4G *obd = NULL;
    mutex.lock();
    obd = thread_pond[sockfd];
    _size = obd->crecv(sockfd, buf, _rsize);
    mutex.unlock();
    return _size;
}
static qint64 cmrecv(const int sockfd, void *buf, const uint16_t _rsize, int msecs)
{
    qint64 _size=0;
    OBDII_4G *obd = NULL;
    mutex.lock();
    obd = thread_pond[sockfd];
    _size = obd->crecv(sockfd, buf, _rsize, msecs);
    mutex.unlock();
    return _size;
}
#if 0
#define   LOAD_FILE   1
static char* load_file(const char* filename, long* const size)
{
    static char filebin[2*1024*1024]; // 2MB
    long _size=0;
    size_t count=0;
    FILE* fd = fopen(filename, "r");
    if(NULL == fd)
    {
        printf("file %s not exist! \n", filename);  fflush(stdout);
        return NULL;
    }
    else
    {
        fseek(fd, 0, SEEK_END);
        _size = ftell(fd);
        fseek(fd, 0, SEEK_SET);
        printf("%s@%d _size:%ld\n", __func__, __LINE__, _size); fflush(stdout);
        // read
        memset(filebin, 0xFF, sizeof (filebin));
        count = fread(filebin, (size_t)_size, 1, fd);
        fclose(fd);
        printf("%s@%d fread _size:%ld count:%lld\n", __func__, __LINE__, _size, count); fflush(stdout);
        //if(1!=count) return NULL;
        //pr_debug("%s@%d fread _size:%d\n", __func__, __LINE__, _size);
        *size = _size;
        return filebin;
    }
}
#else
#define   LOAD_FILE   0
#endif

#include<fcntl.h>
//static uint8_t status=0;
static enum upload_status status=STATUS_QUERY_CFG;
static uint8_t timeout = 0;
//struct cfg_data _cfg_data;
#define TIMEOUT     7
#define WSN_LEN     12
#define DOWNLOAD    fw_path  // "download.bin"
static void obd_upload_start(void)
{
    status=STATUS_QUERY_CFG;
}
static enum upload_status obd_upload(const int sockfd, send_func send)
{
    int len = 0;
    int ret = 0;
    qint64 _size=0;
    const uint8_t wsn[32]="102903420018";
    static char buf[1024*10];
    const char Model[16] = "OBD1234567890AB";
    //time_t timer = time(NULL);
    uint32_t checksum;
    int fd = 0;
#if LOAD_FILE
    char* fw;
    long fw_size=0;
#endif
    uint8_t buffer[sizeof(struct upload)];
    // upload_init(const enum upload_cmd _cmd, const uint16_t pack_total, const uint16_t pack_index, const uint32_t checksum, const uint8_t Model[16], const uint8_t data[512], const uint16_t data_len);
    struct upload* _load = NULL;
    memset(buffer, 0, sizeof (buffer));
    if(STATUS_QUERY_CFG==status)
    {
#if LOAD_FILE
        fw = load_file("./upload/OBD1234567890AB.cfg", &fw_size);  // 获取文件
        if(NULL==fw)
        {
            printf("read file %s fail!\n", "./upload/OBD1234567890AB.cfg"); fflush(stdout);
            checksum = 0x012345678;
        }
        else
        {
            checksum = fast_crc16(0, (unsigned char *)fw, fw_size);
        }
#else
        checksum = crc_form_file(config_path, buf, sizeof(buf) );
#endif
        //printf("%s@%d checksum:0x%04X\n", __func__, __LINE__, checksum); fflush(stdout);
        _load = upload_init(UPLOAD_QUERY_CFG, 0, 10*1024, checksum, Model, wsn, 12);
        len = upload_encode(_load, buffer, sizeof (buffer));
        len = _agree_obd->encode(buffer, len, obd_buf, sizeof (obd_buf));
        //printf("login pack encode len : %d\n", len);
//        socket->write((char*)obd_buf, len);
//        socket->flush();
//        socket->waitForBytesWritten();
        send(sockfd, (char*)obd_buf, len);
        QThread::msleep(1000);
//        socket->waitForReadyRead();
//        _size = socket->read(buf, sizeof (buf));
        _size = crecv(sockfd, buf, sizeof (buf));
        ret = decode_client(_agree_obd, (const uint8_t*)buf, _size, msg_buf, sizeof (msg_buf), sockfd, csend);
        if(STATUS_CLIENT_DOWN==ret)
        {
            status = STATUS_UPLOAD_CFG;
            timeout = 0;
        }
        if(STATUS_CLIENT_DONE==ret)
        {
            status = STATUS_QUERY_FW;
            timeout = 0;
        }
        timeout++;
        if(_size>0) timeout=0;
        if(timeout>TIMEOUT) status = STATUS_TIMEOUT;
    }
    else if(STATUS_UPLOAD_CFG==status)
    {
//        socket->waitForReadyRead();
//        _size = socket->read(buf, sizeof (buf));
        _size = crecv(sockfd, buf, sizeof (buf));
        ret = decode_client(_agree_obd, (const uint8_t*)buf, _size, msg_buf, sizeof (msg_buf), sockfd, csend);
        if(STATUS_CLIENT_DONE==ret)
        {
            printf("CFG rename: %s %s\n", download_cfg_temp, config_path); fflush(stdout);
            status = STATUS_QUERY_FW;
            timeout = 0;
            fd = open(config_path, O_RDONLY, 0);
            if(0 <= fd)
            {
                close(fd);
                //remove("/OBD.cfg");
                unlink(config_path);
            }
            //rename(path, "/OBD.cfg");
            rename(download_cfg_temp, config_path);
            //decode_cfg(&_cfg_data, config_path, msg_buf, sizeof (msg_buf));
        }
        if(ERR_CLIENT_DOWN==ret)
        {
            status = STATUS_QUERY_FW;
            timeout = 0;
        }
        timeout++;
        if(_size>0) timeout=0;
        if(timeout>TIMEOUT) status = STATUS_TIMEOUT;
    }
#if 1
    else if(STATUS_QUERY_FW == status)
    {
#if LOAD_FILE
        fw = load_file("./upload/OBD1234567890AB.bin", &fw_size);  // 获取文件
        if(NULL==fw)
        {
            printf("read file %s fail!\n", "./upload/OBD1234567890AB.bin"); fflush(stdout);
            checksum = 0x012345678;
        }
        else
        {
            checksum = fast_crc16(0, (unsigned char *)fw, fw_size);
        }
#else
        checksum = crc_form_file(fw_path, buf, sizeof(buf) );
#endif
        printf("%s@%d checksum:0x%04X\n", __func__, __LINE__, checksum); fflush(stdout);
        _load = upload_init(UPLOAD_QUERY_FW, 0, 10*1024, checksum, Model, wsn, 12);
        len = upload_encode(_load, buffer, sizeof (buffer));
        len = _agree_obd->encode(buffer, len, obd_buf, sizeof (obd_buf));
        //printf("login pack encode len : %d\n", len);
//        socket->write((char*)obd_buf, len);
//        socket->flush();
//        socket->waitForBytesWritten();
        send(sockfd, (char*)obd_buf, len);
        QThread::msleep(1000);
//        socket->waitForReadyRead();
//        _size = socket->read(buf, sizeof (buf));
        _size = crecv(sockfd, buf, sizeof (buf));
        ret = decode_client(_agree_obd, (const uint8_t*)buf, _size, msg_buf, sizeof (msg_buf), sockfd, csend);
        if(STATUS_CLIENT_DOWN==ret)
        {
            status = STATUS_UPLOAD_FW;
            timeout = 0;
        }
        if(STATUS_CLIENT_DONE==ret)
        {
            status = STATUS_JUMP;
            timeout = 0;
        }
        timeout++;
        if(_size>0) timeout=0;
        if(timeout>TIMEOUT) status = STATUS_TIMEOUT;
    }
    else if(STATUS_UPLOAD_FW==status)
    {
//        socket->waitForReadyRead();
//        _size = socket->read(buf, sizeof (buf));
        _size = crecv(sockfd, buf, sizeof (buf));
        ret = decode_client(_agree_obd, (const uint8_t*)buf, _size, msg_buf, sizeof (msg_buf), sockfd, csend);
        //printf("rename[%d]: %s %s\n", ret, download_fw_temp, DOWNLOAD); fflush(stdout);
        if(STATUS_CLIENT_DONE==ret)
        {
            status = STATUS_REBOOT;
            timeout = 0;
            //printf("rename: %s %s\n", download_fw_temp, DOWNLOAD); fflush(stdout);
            fd = open(DOWNLOAD, O_RDONLY, 0);
            if(0 <= fd)
            {
                close(fd);
                //remove(DOWNLOAD);
                unlink(DOWNLOAD);
            }
            //rename(path, DOWNLOAD);
            rename(download_fw_temp, DOWNLOAD);
        }
        if(ERR_CLIENT_DOWN==ret)
        {
            status = STATUS_ERR;
            timeout = 0;
        }
        timeout++;
        if(_size>0) timeout=0;
        if(timeout>TIMEOUT) status = STATUS_TIMEOUT;
    }
#endif
    else if(STATUS_TIMEOUT==status)
    {
        status = STATUS_RUN;
    }
    else if(STATUS_REBOOT==status)
    {
        status = STATUS_RUN;
    }
    else if(STATUS_JUMP==status)
    {
        status = STATUS_RUN;
    }
    else if(STATUS_ERR==status)
    {
        status = STATUS_RUN;
    }
    else
    {
        QThread::msleep(1000);
    }
    return status;
}



void OBDII_4G::connected()
{
    qDebug() << "SocketClient::readyRead " << socket->readAll();
}

void OBDII_4G::readyRead()
{
    qDebug() << "SocketClient::connected  successfully";
}

void OBDII_4G::error(QAbstractSocket::SocketError socketError)
{
    qDebug() << "SocketClient::error " << socketError;
}


void SocketThreadClient::doWork(const QString parameter)
{
    qDebug() << "Client run " + parameter;
    uint32_t count=0;
    enum upload_status _upload;
    int push = 0;
    if(0!=init(hostName, port))
    {
        emit resultReady("Dont have memery!", NULL);
        qDebug() << "Client exit";
        return ;
    }
    emit resultReady("登录指令!", NULL);
    obd_login(thread_id, csend);
download:
    QThread::msleep(1000);
    _upload=STATUS_QUERY_CFG;
    obd_upload_start();
    while(is_run())
    {
        QThread::msleep(10);
        count++;
        _upload = obd_upload(thread_id, csend);
        //qDebug() << "run--"+QString::number(count);
        emit resultReady("run--"+parameter+"--"+QString::number(count)+" _upload:"+QString::number(_upload), NULL);
        qDebug() << "run--"+parameter+"--"+QString::number(count)+" _upload:"+QString::number(_upload);
        if(STATUS_RUN==_upload) break;
    }
    emit resultReady("校时指令!", NULL);
    obd_UTC(thread_id, csend);
    QThread::msleep(1000);
    emit resultReady("登出指令!", NULL);
    obd_logout(thread_id, csend);
    QThread::msleep(1000);
    while(is_run())
    {
        //qDebug() << "run--"+QString::number(count);
        //emit resultReady("Client run--"+QString::number(count), NULL);
        emit resultReady("run--"+parameter+"--"+QString::number(count), NULL);
        //qDebug() << "run--" << parameter << "--" << QString::number(count);
        count++;
        obd_mutex.lock();
        push = obd_report(thread_id, csend);
        obd_mutex.unlock();
        if(1==push) goto download;
        QThread::msleep(1000);
        if(!is_run()) break;
        obd_mutex.lock();
        push = obd_report_later(thread_id, csend);
        obd_mutex.unlock();
        if(1==push) goto download;
        QThread::msleep(1000);
    }
    /* ... here is the expensive or blocking operation ... */
    emit resultReady("Client exit", NULL);
    qDebug() << "client " << parameter << " exit";

    if(socket->isOpen()) socket->close();
    delete socket;
    socket = nullptr;
    mutex.lock();
    thread_pond[thread_id] = nullptr;
    mutex.unlock();
}

void SocketThreadDownload::doWork(const QString parameter)
{
    qDebug() << "download run " + parameter;
    uint32_t count=0;
    enum upload_status _upload;
    if(0!=init(hostName, port))
    {
        emit resultReady("Dont have memery!", NULL);
        qDebug() << "Download exit";
        return ;
    }
#if 1
    emit resultReady("登录指令!", NULL);
    obd_login(thread_id, csend);
    QThread::msleep(500);
    emit resultReady("校时指令!", NULL);
    obd_UTC(thread_id, csend);
    QThread::msleep(500);
    emit resultReady("登出指令!", NULL);
    obd_logout(thread_id, csend);
    QThread::msleep(500);
#endif
    while(is_run())
    {
        QThread::msleep(10);
        //qDebug() << "run--"+QString::number(count);
        //emit resultReady("Download run--"+QString::number(count)+" _upload:"+QString::number(_upload), NULL);
        emit resultReady("run--"+parameter+"--"+QString::number(count)+" _upload:"+QString::number(_upload), NULL);
        count++;
        _upload = obd_upload(thread_id, csend);
        if(STATUS_RUN==_upload) break;
    }
    /* ... here is the expensive or blocking operation ... */
    emit resultReady("Download Done!", NULL);
    qDebug() << "Download exit";

    if(socket->isOpen()) socket->close();
    delete socket;
    socket = nullptr;
    mutex.lock();
    thread_pond[thread_id] = nullptr;
    mutex.unlock();
}
